import {
  Component, OnInit, Output, Input, EventEmitter, ViewChild, TemplateRef, HostBinding, NgZone, OnDestroy
} from '@angular/core';
import { NotifyService } from '@farris/ui-notify';
import { TreeNode } from '@farris/ui-treetable';
import { ElementPropertyConfig, PropertyChangeObject } from '@farris/ide-property-panel';
import { ListFilterService } from './list-filter.service';
import { cloneDeep } from 'lodash-es';
import { FormSchemaEntityField$Type, FormSchemaEntityFieldTypeName, DesignViewModelService, DomService } from '@farris/designer-services';
import { MessagerService } from '@farris/ui-messager';
import { MultiSelectComponent } from '@farris/ui-multi-select';
import { Subscription } from 'rxjs';
import { ListFilterFieldCreator } from './query-data/field-control-data';

@Component({
  selector: 'app-list-filter-fields-editor',
  templateUrl: './list-filter-fields-editor.component.html',
  providers: [ListFilterService]
})
export class ListFilterFieldsEditorComponent implements OnInit, OnDestroy {
  @Output() closeModal = new EventEmitter<any>();
  @Output() submitModal = new EventEmitter<any>();
  @Input() value;
  @Input() editorParams = { viewModelId: '', controlSource: '' };

  /** 是否显示属性面板 */
  @Input() showPropertyPanel = true;

  @ViewChild('footer') modalFooter: TemplateRef<any>;
  modalConfig = {
    title: '筛选条字段编辑器',
    width: 1000,
    height: 700,
    showButtons: true,
    showMaxButton: true
  };
  // 筛选条字段
  fieldConfigs = [];

  // 左侧树表数据
  treeData: TreeNode[] = [];

  // 当前可选的所有字段ID
  treeNodeIds: string[] = [];
  plainTreeNodes: TreeNode[] = [];

  // 选中的字段
  selectedFieldIds = [];

  // 右侧选中行对应的schema字段信息
  selectedSchemaField;


  // 属性面板配置
  propertyConfig: ElementPropertyConfig[];

  // 属性面板值
  propertyData;

  @HostBinding('class')
  class = 'd-flex  h-100';

  @ViewChild(MultiSelectComponent) multiSelectCmp: MultiSelectComponent;

  timer: any;

  private triggerSaveAndCloseEditorSub: Subscription;

  /** 记录编辑器刚打开时的DOM actions数据。编辑器内部交互面板在操作过程中可能会修改actions节点，导致点击【取消】按钮时无法还原actions数据。所以这里记录一份原始数据，方便还原。 */
  private previousActions: any[];

  /** 记录编辑器刚打开时的DOM viewmodels数据。编辑器内部交互面板在操作过程中可能会修改viewmodels节点，导致点击【取消】按钮时无法还原viewmodels数据。所以这里记录一份原始数据，方便还原。 */
  private previousViewModels: any[];

  constructor(
    private dgVMService: DesignViewModelService, private notifyService: NotifyService,
    private ListFilterServ: ListFilterService, private msgService: MessagerService,
    private domService: DomService,
    private ngZone: NgZone) { }

  ngOnInit(): void {
    if (!this.editorParams || !this.value) {
      this.fieldConfigs = [];
    } else {
      this.fieldConfigs = cloneDeep(this.value);
    }
    this.treeData = this.dgVMService.getAllFields2TreeByVMId(this.editorParams.viewModelId);


    this.filterAllowedType(this.treeData);

    this.adpatOldForm();

    this.selectedFieldIds = this.fieldConfigs.map(v => v.id);

    this.filterSchemFields();

    // 触发保存并关闭当前窗口
    this.triggerSaveAndCloseEditorSub = this.ListFilterServ.triggerSaveAndCloseEditor.subscribe(() => {
      this.clickConfirm();
    });

    // 默认选中第一行
    if (this.selectedFieldIds.length && this.multiSelectCmp['selectItem']) {
      this.ngZone.runOutsideAngular(() => {
        this.timer = setTimeout(() => {
          this.multiSelectCmp['selectItem'](this.selectedFieldIds[0]);
        });
      });
    }

    this.previousActions = cloneDeep(this.domService.module.actions);
    this.previousViewModels = cloneDeep(this.domService.module.viewmodels);
  }

  ngOnDestroy(): void {
    this.ListFilterServ.triggerSaveAndCloseEditor.unsubscribe();
    if (this.timer) {
      clearTimeout(this.timer);
    }

    if (this.triggerSaveAndCloseEditorSub) {
      this.triggerSaveAndCloseEditorSub.unsubscribe();
    }
  }

  /**
   * 适配旧表单的筛选调配置
   */
  private adpatOldForm() {
    if (this.fieldConfigs.length === 0) {
      return;
    }
    // 检测第一条数据id是否为字段id
    // const firstField = this.fieldConfigs[0];
    // const schemFieldData = this.plainTreeNodes.find(n => n.data.path === firstField.labelCode);

    // if (!schemFieldData || schemFieldData.data.id === firstField.id) {
    //   return;
    // }

    this.fieldConfigs.forEach(config => {

      const schemaFieldNode = this.plainTreeNodes.find(n => n.data.path === config.labelCode);
      if (schemaFieldNode) {
        // 旧表单的id可能不是字段id，此处强制改成字段id
        config.id = schemaFieldNode.data.id;

        if (config.control && (config.control.controltype === 'number' || config.control.controltype === 'flexibleNumber')) {
          // 适配旧表单数值区间控件缺少精度属性
          if (!Object.keys(config.control).includes('precision')) {
            config.control.precision = schemaFieldNode.data.type && schemaFieldNode.data.type.precision;
          }
          // 适配字段切换数值和大数值的场景
          config.control.bigNumber = schemaFieldNode.data.type.name === FormSchemaEntityFieldTypeName.BigNumber;

        }


      }
    });
  }

  /**
   * 过滤筛选条支持的字段
   * @param treeData 树数据
   */
  filterAllowedType(treeData: TreeNode[]) {
    treeData.forEach(treeNode => {

      if (treeNode.data.$type === FormSchemaEntityField$Type.SimpleField) {
        if (!this.ListFilterServ.allowedFieldType.includes(treeNode.data.type.name)) {
          treeNode.selectable = false;
        } else {
          this.treeNodeIds.push(treeNode.data.id);
        }
        this.plainTreeNodes.push(treeNode);
      }
      if (treeNode.children && treeNode.children.length > 0) {
        this.filterAllowedType(treeNode.children);
      }
    });
  }
  filterSchemFields() {
    const removedFields = [];
    this.selectedFieldIds.forEach(id => {
      if (!this.treeNodeIds.includes(id)) {
        // schema中已移除的字段
        const field = this.fieldConfigs.find(f => f.id === id);
        if (field) {
          removedFields.push(field.name);
        }
        this.fieldConfigs = this.fieldConfigs.filter(f => f.id !== id);
        this.selectedFieldIds = this.selectedFieldIds.filter(fid => fid !== id);
      }
    });
    if (removedFields.length > 0) {
      this.ngZone.runOutsideAngular(() => {
        setTimeout(() => {
          this.msgService.warning('已选择字段【' + removedFields.toString() + '】已移除、变更或暂不支持添加，点击确定后将自动删除字段');
        });
      });
    }
  }

  /**
   * 改变选中字段事件
   * @param e 选中的行数据
   */
  changeSelectField(e: any[]) {
    if (!e) {
      return;
    }
    const fieldConfigs = [];
    if (e.length === 0) {
      this.propertyConfig = [];
      this.fieldConfigs = [];
      return;
    }
    e.forEach(data => {
      const co = this.fieldConfigs.find(c => c.id === data.id);
      if (co) {
        fieldConfigs.push(co);
      } else {
        const newConfig = ListFilterFieldCreator.getFilterField(data);
        if (newConfig.control) {
          fieldConfigs.push(newConfig);
        }
      }
    });
    this.fieldConfigs = fieldConfigs;


    if (this.selectedSchemaField && !fieldConfigs.find(f => f.id === this.selectedSchemaField.id)) {
      this.propertyConfig = [];
    }
  }

  /**
   * 切换右侧行
   * @param e 行数据
   */
  changeRightSelect(e) {
    if (!e.selected || !e.data) {
      return;
    }
    this.triggerShowPropertyPanel(e.data);
  }

  triggerShowPropertyPanel(rowData: any) {
    this.selectedSchemaField = rowData;

    this.propertyData = this.fieldConfigs.find(f => f.id === rowData.id);
    this.propertyConfig = this.ListFilterServ.getPropertyConfig(rowData, this.propertyData,
      this.editorParams.viewModelId, this.editorParams.controlSource, this.fieldConfigs);

  }

  propertyChanged(changeObject: PropertyChangeObject) {

    // 修改控件名称后，要同步控件的路径信息,用于交互面板的显示
    if (changeObject.propertyID === 'name') {

      this.domService.controlBasicInfoMap.set(this.propertyData.id, {
        showName: changeObject.propertyValue,
        parentPathName: `筛选条 > ${changeObject.propertyValue}`
      });
    }


  }

  submitPropertyModal(data: { changeObject: PropertyChangeObject, parameters: any }) {
    const changeObject = data.changeObject;

    // 交互面板变更后，同步控件的路径信息
    if (changeObject.categoryId === 'eventsEditor') {

      this.domService.controlBasicInfoMap.set(this.propertyData.id, {
        showName: this.propertyData.name,
        parentPathName: `筛选条 > ${this.propertyData.name}`
      });
    }

  }
  clickCancel() {
    this.domService.module.actions = this.previousActions;
    this.domService.module.viewmodels = this.previousViewModels;

    this.closeModal.emit();
  }

  clickConfirm() {
    if (this.fieldConfigs.length === 0) {
      this.notifyService.warning('请选择字段');
      return;
    }

    this.submitModal.emit({ value: this.fieldConfigs });
  }
}
